﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;

namespace Component.Utilities
{
	public class ImagePlus
	{
		// Fields
		private int ch;
		private int cw;
		private Image image;
		private int oh;
		private int ow;
		private int ox;
		private int oy;
		private List<PictureWater> pictures;
		private List<TextWater> texts;
		private int th;
		private int tw;
		private int tx;
		private int ty;

		// Methods
		public ImagePlus(Stream stream)
		{
			this.texts = new List<TextWater>();
			this.pictures = new List<PictureWater>();
			this.image = Image.FromStream(stream);
			this.ResetSize(this.image.Width, this.image.Height);
		}

		public ImagePlus(string filepath)
		{
			this.texts = new List<TextWater>();
			this.pictures = new List<PictureWater>();
			this.image = Image.FromFile(filepath);
			this.ResetSize(this.image.Width, this.image.Height);
		}

		public void AddPicture(string path, int place, int offsetX, int offsetY, float alpha, float size)
		{
			PictureWater item = new PictureWater();
			item.path = path;
			item.place = place;
			item.offsetX = offsetX;
			item.offsetY = offsetY;
			item.alpha = alpha;
			item.size = size;
			this.pictures.Add(item);
		}

		public void AddText(string text, int place, int offsetX, int offsetY, int color, float alpha, string family, float size)
		{
			TextWater item = new TextWater();
			item.text = text;
			item.place = place;
			item.offsetX = offsetX;
			item.offsetY = offsetY;
			item.color = color;
			item.alpha = alpha;
			item.family = family;
			item.size = size;
			this.texts.Add(item);
		}

		~ImagePlus()
		{
			if (this.image != null)
			{
				this.image.Dispose();
			}
		}

		private Point GetPlace(int place, int offsetX, int offsetY, int w, int h)
		{
			int x = 0;
			int num2 = 0;
			if (place == 0)
			{
				place = 5;
			}
			switch (place)
			{
				case 1:
					x = 0;
					num2 = 0;
					break;

				case 2:
					x = (this.cw - w) / 2;
					num2 = 0;
					break;

				case 3:
					x = this.cw - w;
					num2 = 0;
					break;

				case 4:
					x = 0;
					num2 = (this.ch - h) / 2;
					break;

				case 5:
					x = (this.cw - w) / 2;
					num2 = (this.ch - h) / 2;
					break;

				case 6:
					x = this.cw - w;
					num2 = (this.ch - h) / 2;
					break;

				case 7:
					x = 0;
					num2 = this.ch - h;
					break;

				case 8:
					x = (this.cw - w) / 2;
					num2 = this.ch - h;
					break;

				case 9:
					x = this.cw - w;
					num2 = this.ch - h;
					break;
			}
			x += offsetX;
			return new Point(x, num2 + offsetY);
		}

		public void MakeThumbnail(int w, int h, int mode)
		{
			this.ResetSize(this.image.Width, this.image.Height);
			if (((w != 0) || (h != 0)) && ((w != this.ow) || (h != this.oh)))
			{
				int ow = this.ow;
				int oh = this.oh;
				this.tw = this.cw = w;
				this.th = this.ch = h;
				switch (mode)
				{
					case 1:
						if ((ow * h) <= (w * oh))
						{
							if (h == 0)
							{
								this.th = (this.oh * this.tw) / this.ow;
								this.ch = this.th;
							}
							else
							{
								this.tw = (this.ow * this.th) / this.oh;
								this.cw = this.tw;
							}
							break;
						}
						if (w != 0)
						{
							this.th = (this.oh * this.tw) / this.ow;
							this.ch = this.th;
							break;
						}
						this.tw = (this.ow * this.th) / this.oh;
						this.cw = this.tw;
						break;

					case 2:
						if ((ow * h) <= (w * oh))
						{
							if (h == 0)
							{
								this.th = (this.oh * this.tw) / this.ow;
								this.ch = this.th;
							}
							else
							{
								this.tw = (this.ow * this.th) / this.oh;
								this.tx = (this.cw - this.tw) / 2;
							}
							break;
						}
						if (w != 0)
						{
							this.th = (this.oh * this.tw) / this.ow;
							this.ty = (this.ch - this.th) / 2;
							break;
						}
						this.tw = (this.ow * this.th) / this.oh;
						this.cw = this.tw;
						break;

					case 3:
						if ((ow * h) <= (w * oh))
						{
							if (h == 0)
							{
								this.th = (this.oh * this.tw) / this.ow;
								this.ch = this.th;
							}
							else
							{
								this.oh = (this.th * this.ow) / this.tw;
								this.oy = (oh - this.oh) / 2;
							}
							break;
						}
						if (w != 0)
						{
							this.ow = (this.tw * this.oh) / this.th;
							this.ox = (ow - this.ow) / 2;
							break;
						}
						this.tw = (this.ow * this.th) / this.oh;
						this.cw = this.tw;
						break;
				}
			}
		}

		private void Reset()
		{
			this.ResetSize(this.image.Width, this.image.Height);
			this.texts.Clear();
			this.pictures.Clear();
		}

		private void ResetSize(int width, int height)
		{
			this.ox = this.oy = this.tx = this.ty = 0;
			this.ow = this.tw = this.cw = width;
			this.oh = this.th = this.ch = height;
		}

		public void SaveAs(string path)
		{
			this.SaveAs(path, "");
		}

		public void SaveAs(string path, string format)
		{
			Point point;
			Bitmap image = new Bitmap(this.cw, this.ch);
			Graphics graphics = Graphics.FromImage(image);
			graphics.InterpolationMode = InterpolationMode.High;
			graphics.SmoothingMode = SmoothingMode.HighQuality;

			Rectangle des = new Rectangle(this.tx, this.ty, this.tw, this.th);
			Rectangle src = new Rectangle(this.ox, this.oy, this.ow, this.oh);
			graphics.FillRectangles(new SolidBrush(Color.White), new Rectangle[] { src });

			graphics.TranslateTransform(1, 0);
			graphics.DrawImage(this.image, des, src, GraphicsUnit.Pixel);

			foreach (PictureWater water in this.pictures)
			{
				int num;
				int num2;
				Image image2 = Image.FromFile(water.path);
				ImageAttributes imageAttr = new ImageAttributes();
				if (water.size < 1f)
				{
					num = (int)(this.cw * water.size);
					num2 = (int)(this.ch * water.size);
					if ((image2.Width * num2) > (image2.Height * num))
					{
						num2 = (image2.Height * num) / image2.Width;
					}
					else
					{
						num = (image2.Width * num2) / image2.Height;
					}
				}
				else
				{
					num = (int)(image2.Width * water.size);
					num2 = (int)(image2.Height * water.size);
				}
				point = this.GetPlace(water.place, water.offsetX, water.offsetY, num, num2);
				float[][] numArray2 = new float[5][];
				float[] numArray3 = new float[5];
				numArray3[0] = 1f;
				numArray2[0] = numArray3;
				numArray3 = new float[5];
				numArray3[1] = 1f;
				numArray2[1] = numArray3;
				numArray3 = new float[5];
				numArray3[2] = 1f;
				numArray2[2] = numArray3;
				numArray3 = new float[5];
				numArray3[3] = water.alpha;
				numArray2[3] = numArray3;
				numArray3 = new float[5];
				numArray3[4] = 1f;
				numArray2[4] = numArray3;
				float[][] newColorMatrix = numArray2;
				ColorMatrix matrix = new ColorMatrix(newColorMatrix);
				imageAttr.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
				graphics.DrawImage(image2, new Rectangle(point.X, point.Y, num, num2), 0, 0, image2.Width, image2.Height, GraphicsUnit.Pixel, imageAttr);
				image2.Dispose();
			}
			foreach (TextWater water2 in this.texts)
			{
				float size;
				Font font;
				SizeF ef = new SizeF();
				if (water2.size < 1f)
				{
					size = 20f;
					font = new Font(water2.family, size, FontStyle.Regular, GraphicsUnit.Pixel);
					ef = graphics.MeasureString(water2.text, font);
					size *= (this.cw * water2.size) / ef.Width;
				}
				else
				{
					size = water2.size;
				}
				font = new Font(water2.family, size, FontStyle.Regular, GraphicsUnit.Pixel);
				ef = graphics.MeasureString(water2.text, font);
				SolidBrush brush = new SolidBrush(Color.FromArgb((int)(water2.alpha * 255f), Color.FromArgb(water2.color)));
				point = this.GetPlace(water2.place, water2.offsetX, water2.offsetY, (int)ef.Width, (int)ef.Height);
				graphics.DrawString(water2.text, font, brush, (PointF)point);
			}
			try
			{
				try
				{
					string str = format.ToLower();
					if (str == null)
					{
						goto Label_0427;
					}
					if (!(str == ""))
					{
						if (str == "gif")
						{
							goto Label_03FA;
						}
						if (str == "png")
						{
							goto Label_0409;
						}
						if (str == "bmp")
						{
							goto Label_0418;
						}
						goto Label_0427;
					}
					image.Save(path, this.Image.RawFormat);
					goto Label_0453;
				Label_03FA:
					image.Save(path, ImageFormat.Gif);
					goto Label_0453;
				Label_0409:
					image.Save(path, ImageFormat.Png);
					goto Label_0453;
				Label_0418:
					image.Save(path, ImageFormat.Bmp);
					goto Label_0453;
				Label_0427:
					image.Save(path, ImageFormat.Jpeg);
				}
				catch (Exception exception)
				{
					throw exception;
				}
			}
			finally
			{
				image.Dispose();
				graphics.Dispose();
			}
		Label_0453:
			this.Reset();
		}

		// Properties
		public Image Image
		{
			get
			{
				return this.image;
			}
		}

		public string Version
		{
			get
			{
				return "Fonshen.NET.ImagePlus Version 1.00";
			}
		}
	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct PictureWater
	{
		public string path;
		public int place;
		public int offsetX;
		public int offsetY;
		public float alpha;
		public float size;
	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct TextWater
	{
		public string text;
		public int place;
		public int offsetX;
		public int offsetY;
		public int color;
		public float alpha;
		public string family;
		public float size;
	}

}
